#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "do_rw.h"
#include "do_test.h"
#include "thread_ctrl.h"
#include "ietDoLib.h"

/* 发送 DO 数据线程函数 */
void *send_do_thread(void *arg)
{
    struct do_dev_t *pdev = (struct do_dev_t *)arg;
    struct do_param_t *pparam = (struct do_param_t *)pdev->parent;
    struct thread_param_t *pthread = pdev->write_thread;
    int ret = 0;
    int i = 0;
    uint64_t j = 0;
    unsigned int value;
    struct DomParam devParam = {
        .timeOutEnable = pdev->timeout_sta,
        .timeOut = pdev->timeout_sec,
    };
    struct PulseParam devPulseParam = {
        .number = pdev->pulse_num,
        .pulsewidth = pdev->pulse_high,
        .pulseInterval = pdev->pulse_cycle,
    };

    /* 检查参数是否有效 */
    if (!pthread || !pthread->name) {
        fprintf(stderr, "Invalid parameters for %s\n", __func__);
        return NULL;
    }

    /* 线程取消 SIGUSR1 的阻塞 */
    init_thread_user_signal();
    DOMInit(pdev->index, devParam);
    // printf("Start %s send thread...\n", pdev->path);
    while (!pthread->exit_sig) {
        for (i = 0; (pparam->write_cnt == -1 || i < pparam->write_cnt) && !pthread->exit_sig; i++) {
            switch (pdev->mode) {
            case DO_MOD_LEVEL:
                /* 配置 DO 电平 */
                ret = DOMWrite(pdev->index, pdev->set_val);
                if (ret < 0) {
                    fprintf(stderr, "DOMWrite DO %2d level %d failed\n", pdev->index, pdev->set_val);
                    return NULL;
                }
                printf("DOMWrite DO %2d level %d\n", pdev->index, pdev->set_val);
                usleep(5000);
                for (j = 0; j < pparam->max_num; j++) {
                    ret = DOMRead(j, &value);
                    if (ret < 0) {
                        fprintf(stderr, "DOMRead DO %2ld level %d failed\n", j, value);
                        return NULL;
                    }
                    printf("DOMRead  DO %2ld level %d\n", j, value);
                }
                break;
            case DO_MOD_PULSE:
                /* 配置 DO 脉冲 */
                ret = DOMPulseWrite(pdev->index, devPulseParam);
                if (ret < 0) {
                    fprintf(stderr, "DOMPulseWrite DO %2d pulse high %dms cycle %dms num %d failed\n", 
                             pdev->index, pdev->pulse_high, pdev->pulse_cycle, pdev->pulse_num);
                    return NULL;
                }
                printf("DOMPulseWrite DO %2d pulse high %dms cycle %dms num %d\n", 
                         pdev->index, pdev->pulse_high, pdev->pulse_cycle, pdev->pulse_num);
                usleep(10000);
                for (j = 0; j < (pdev->pulse_cycle * pdev->pulse_num); j++) {
                    usleep(1000);
                    if (pthread->exit_sig) {
                        break;
                    }
                }
                break;
            default:
                fprintf(stderr, "Write %s failed, mode=%d not support\n", pdev->path, pdev->mode);
                break;
            }
        }
        // printf("Write %s %d data done\n", pdev->path, pparam->write_cnt);
        break;
    }
    // printf("%s %s return\n", pdev->path, __func__);

    return NULL;
}
